package mine.code.question.动态规划;

import org.junit.Test;

/**
 * 给出非负整数数组 A ，返回两个非重叠（连续）子数组中元素的最大和，子数组的长度分别为 L 和 M。（这里需要澄清的是，长为 L 的子数组可以出现在长为 M 的子数组之前或之后。）
 * <p>
 * 从形式上看，返回最大的 V，而 V = (A[i] + A[i+1] + ... + A[i+L-1]) + (A[j] + A[j+1] + ... + A[j+M-1]) 并满足下列条件之一：
 * <p>
 * 0 <= i < i + L - 1 < j < j + M - 1 < A.length, 或
 * 0 <= j < j + M - 1 < i < i + L - 1 < A.length.
 *
 * @author caijinnan
 */
public class 两个非重叠子数组的最大和 {

    @Test
    public void run() {
//      [8,20,6,2,20,17,6,3,20,8,12]
//5
//4
        int[] nums = {8, 20, 6, 2, 20, 17, 6, 3, 20, 8, 12};
        int firstLen = 5;
        int secondLen = 4;
        System.out.println(maxSumTwoNoOverlap(nums, firstLen, secondLen));
    }

    public int maxSumTwoNoOverlap(int[] nums, int firstLen, int secondLen) {
        int n = nums.length;
        int[] sum = new int[n + 1];
        for (int i = 0; i < n; i++) sum[i + 1] = sum[i] + nums[i];
        if (firstLen > secondLen) {
            int t = firstLen;
            firstLen = secondLen;
            secondLen = t;
        }
        int[][] dp = new int[n + 1][2];
        int max = 0;
        for (int i = firstLen; i <= n; i++) {
            int s1 = sum[i] - sum[i - firstLen];
            dp[i][0] = Math.max(dp[i - 1][0], s1);
            max = Math.max(max, s1 + dp[i - firstLen][1]);
            if (i >= secondLen) {
                int s2 = sum[i] - sum[i - secondLen];
                dp[i][1] = Math.max(dp[i - 1][1], s2);
                max = Math.max(max, s2 + dp[i - secondLen][0]);
            }
        }
        return max;
    }
}
